package cn.fl.project.controller;

import cmm.user.facade.system.api.IPriorityApiService;
import cmm.user.facade.system.api.ISysOrgApiService;
import cmm.user.facade.system.api.ISysUsrApiService;
import cmm.user.facade.system.condition.SysOrgQueryCondition;
import cmm.user.facade.system.dto.SysOrgDTO;
import cmm.user.facade.system.dto.SysUsrDTO;
import cmm.user.facade.system.dto.SysUsrDatAuthRDTO;
import cn.cmm.base.framework.constant.BaseConstant;
import cn.cmm.base.framework.exception.BaseException;
import cn.cmm.base.framework.utils.CollectionUtils;
import cn.fl.commons.result.ResponseData;
import cn.fl.framework.base.context.CurrentThreadContext;
import cn.fl.preloan.enums.LogBusinessTypeEnum;
import cn.fl.project.condition.SysOrgBpCfgCondition;
import cn.fl.project.constant.PrjBscInfoConstant;
import cn.fl.project.service.PrjOrgBpLimitService;
import cn.fl.project.vo.SysOrgBpCfgEditLogVO;
import cn.fl.project.vo.SysOrgBpCfgVO;
import cn.lionbridgecapital.loan.model.utils.DecimalUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lionbridge.log.ext.ExtSlf4jLogger;
import com.lionbridge.log.ext.ExtSlf4jLoggerBuilder;
import com.lionbridge.log.ext.LogTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Controller
@RequestMapping("/project/orgBpLimit/")
public class PrjOrgBpLimitController {
    private static ExtSlf4jLogger logger = ExtSlf4jLoggerBuilder.create()
            .setLogger(log).setBusinessType(LogBusinessTypeEnum.QUOTATION_SCHEME.getCode())
            .setSubBusinessType(LogBusinessTypeEnum.QUOTATION_SCHEME.getCode())
            .setLogType(LogTypeEnum.BUSINESS).build().setKeywords("PrjQuatPrpsPayReb");
    @Autowired
    PrjOrgBpLimitService prjOrgBpLimitService ;

    @Autowired
    ISysUsrApiService sysUsrApiService ;
    @Autowired
    ISysOrgApiService sysOrgApiService ;
    @Autowired
    IPriorityApiService priorityApiService ;

    private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");

    @RequestMapping("toOrgBpCfgPage.do")
    public ModelAndView toOrgBpCfgPage(){
        ModelAndView view = new ModelAndView("project/prjorgbplimitcfg/prjOrgBpLimitCfg");
        logger.info("查询重卡事业部本月包牌设备数量占比--start");
        try{
            Map<String, Object> initData = getInitData();
            view.addObject("logList",JSON.toJSONString(initData.get("logList")));
            view.addObject("bpPct",initData.get("bpPct"));
            view.addObject("limitPct",initData.get("limitPct"));
            view.addObject("uncheckCnt",initData.get("uncheckCnt"));
        }catch (Exception e){
            logger.error("查询重卡事业部本月包牌设备数量占比失败,msg:{}",e);
            throw new BaseException("查询重卡事业部本月包牌设备数量占比失败") ;
        }
        logger.info("查询重卡事业部本月包牌设备数量占比--end");
        return view ;
    }

    @ResponseBody
    @RequestMapping("initOrgBpCfgPage.do")
    public ResponseData<Map<String,Object>> initPageData(){
        ResponseData responseData = new ResponseData(ResponseData.FAIL_CODE,"获取数据失败") ;
        try{
            Map<String, Object> data = getInitData();
            if (data != null){
                responseData.setData(data);
                responseData.setCode(ResponseData.SUCCESS_CODE);
                responseData.setSuccess(true);
                responseData.setMessage("获取成功");
            }
            return responseData ;
        }catch (Exception e){
            throw new BaseException("查询数据失败");
        }
    }

    private Map<String,Object> getInitData() throws Exception{
        Map map = new HashMap() ;
        SysOrgBpCfgCondition countCon = new SysOrgBpCfgCondition();
        Date now = new Date();
        Date firstDayOfMonth = format.parse(format.format(now));
        countCon.setStartDt(firstDayOfMonth);
        countCon.setEndDt(now);
        countCon.setOrgCd(PrjBscInfoConstant.CODE_BU_ORG_CD_ZK); // 重卡
        countCon.setOrgTyp(1); // 事业部
        SysOrgBpCfgVO sysOrgBpCfgVO = prjOrgBpLimitService.getOrgBpLimitCount(countCon);
        logger.info("查询包牌数和设备总数" + JSON.toJSONString(sysOrgBpCfgVO));
        Double bpPct = 0d ;
        if (sysOrgBpCfgVO != null && sysOrgBpCfgVO.getAllCount() != null && sysOrgBpCfgVO.getAllCount().intValue() != 0){
            Integer bpCount  = sysOrgBpCfgVO.getBpCount() ;
            Integer allCount = sysOrgBpCfgVO.getAllCount();
            bpPct = DecimalUtils.round(DecimalUtils.div(bpCount,allCount,4) * 100,2);
        }else{
            bpPct = 0d ;
        }
        SysOrgBpCfgCondition  limitCon = new SysOrgBpCfgCondition();
        limitCon.setOrgTyp(1);
        limitCon.setOrgCd(PrjBscInfoConstant.CODE_BU_ORG_CD_ZK);
        limitCon.setLimitTyp(1); // 上限比例
        SysOrgBpCfgVO limitCfg = prjOrgBpLimitService.getBpOrgLimit(limitCon);
        logger.info("查询重卡包牌比例上限" + JSON.toJSONString(limitCfg));
        SysOrgBpCfgCondition  unCheckCon = new SysOrgBpCfgCondition();
        unCheckCon.setOrgTyp(1);
        unCheckCon.setOrgCd(PrjBscInfoConstant.CODE_BU_ORG_CD_ZK);
        unCheckCon.setLimitTyp(2); //  免校验台数
        SysOrgBpCfgVO uncheckCfg = prjOrgBpLimitService.getBpOrgLimit(unCheckCon);
        logger.info("查询重卡免校验台数" + JSON.toJSONString(uncheckCfg));
        Double limitPct = limitCfg.getLimitVal() ;
        Double uncheckCnt = uncheckCfg.getLimitVal() ;
        SysOrgBpCfgCondition logCondition = new SysOrgBpCfgCondition();
        logCondition.setStartDt(firstDayOfMonth);
        logCondition.setEndDt(now);
        logCondition.setOrgCd(PrjBscInfoConstant.CODE_BU_ORG_CD_ZK);
        List<SysOrgBpCfgEditLogVO> sysOrgCfgEditLogs = prjOrgBpLimitService.getSysOrgCfgEditLog(logCondition);
        map.put("bpPct",bpPct);
        map.put("limitPct",limitPct);
        map.put("uncheckCnt",uncheckCnt.intValue());
        map.put("logList",JSON.toJSONString(sysOrgCfgEditLogs));
        return map ;
    }
    /**
     * 修改重卡免校验台数配置
     */
    @ResponseBody
    @RequestMapping("updateUnCheckCount.do")
    public ResponseData updateUnCheckCount(Double count){
        ResponseData responseData = new ResponseData(ResponseData.FAIL_CODE,"修改免校验台数失败") ;
        try{
            logger.info("修改重卡免校验台数,count:" + count);
            SysOrgBpCfgCondition  unCheckCon = new SysOrgBpCfgCondition();
            unCheckCon.setOrgTyp(1);
            unCheckCon.setOrgCd(PrjBscInfoConstant.CODE_BU_ORG_CD_ZK);
            unCheckCon.setLimitTyp(2); //  免校验台数
            SysOrgBpCfgVO uncheckCfg = prjOrgBpLimitService.getBpOrgLimit(unCheckCon);
            logger.info("查询重卡免校验台数" + JSON.toJSONString(uncheckCfg));
            // 更新免校验台数
            SysOrgBpCfgVO sysOrgBpCfgVO = new SysOrgBpCfgVO() ;
            sysOrgBpCfgVO.setOrgCd(PrjBscInfoConstant.CODE_BU_ORG_CD_ZK);
            sysOrgBpCfgVO.setOrgTyp(1);
            sysOrgBpCfgVO.setLimitTyp(2);
            sysOrgBpCfgVO.setLimitVal(Double.valueOf(count));
            Integer integer = prjOrgBpLimitService.updateOrgBpLimitCfg(sysOrgBpCfgVO);
            logger.info("修改包牌配置信息完成:" + integer);
            if (integer != null && integer > 0){
                // 插入修改记录
                SysOrgBpCfgEditLogVO vo = new SysOrgBpCfgEditLogVO() ;
                SysUsrDTO sysUsrDTO = sysUsrApiService.selectSysUsrById(CurrentThreadContext.getCurrentUserId(),"11000","0000");
                logger.info("查询用户信息:" + JSON.toJSONString(sysUsrDTO));
                vo.setUserId(CurrentThreadContext.getCurrentUserId());
                vo.setUserName(CurrentThreadContext.getCurrentUserName()); // 工号
                vo.setOrgCd(PrjBscInfoConstant.CODE_BU_ORG_CD_ZK);
                vo.setOriginVal(uncheckCfg.getLimitVal());
                vo.setNewVal(count);
                vo.setUserNo(sysUsrDTO.getUsrNm());
                vo.setCrtTm(new Date());
                vo.setModTm(new Date());
                vo.setIsDel(0);
                vo.setEditTyp(2);
                Integer result = prjOrgBpLimitService.addSysOrgCfgEditLog(vo);
                if (result != null && result > 0){
                    responseData.setCode(ResponseData.SUCCESS_CODE);
                    responseData.setData(1);
                    responseData.setMessage("修改成功");
                }
            }
        }catch(Exception e){
            logger.error("修改包牌配置信息失败，msg:{}",e);
        }
        return responseData ;
    }
    /**
     * 重卡列表（包牌数、总数、比例等信息）
     */
    @ResponseBody
    @RequestMapping("searchBpCfgForOrgList.do")
    public ResponseData searchBpCfgForOrgList() throws BaseException{
        try{
            ResponseData responseData = new ResponseData(ResponseData.FAIL_CODE,"获取省公司包牌配置信息失败");
            List<SysOrgBpCfgVO> bpOrgLimitCfgList = prjOrgBpLimitService.getBpOrgLimitCfgList(PrjBscInfoConstant.CODE_BU_ORG_CD_ZK);
            logger.info("获取省公司包牌配置信息列表" + JSON.toJSONString(bpOrgLimitCfgList));
            if (bpOrgLimitCfgList == null){
                return responseData ;
            }
            for (SysOrgBpCfgVO vo:bpOrgLimitCfgList){
                SysOrgBpCfgCondition countCon = new SysOrgBpCfgCondition();
                Date now = new Date();
                Date firstDayOfMonth = format.parse(format.format(now));
                countCon.setStartDt(firstDayOfMonth);
                countCon.setEndDt(now);
                countCon.setOrgCd(vo.getOrgCd()); // 重卡-省公司
                countCon.setOrgTyp(2); // 省公司
                SysOrgBpCfgVO sysOrgBpCfgVO = prjOrgBpLimitService.getOrgBpLimitCount(countCon);
                logger.info("sysOrgBpCfgVO" + JSON.toJSONString(sysOrgBpCfgVO));
                if (sysOrgBpCfgVO != null){
                    vo.setBpCount(sysOrgBpCfgVO.getBpCount());
                    vo.setAllCount(sysOrgBpCfgVO.getAllCount());
                }
            }
            responseData.setSuccess(true);
            responseData.setData(bpOrgLimitCfgList);
            responseData.setCode(ResponseData.SUCCESS_CODE);
            responseData.setMessage("获取省公司包牌配置信息成功");
            return responseData;
        }catch (Exception e){
            logger.error("获取省公司包牌配置信息失败，msg{}",e);
            throw new BaseException("获取省公司包牌配置信息失败") ;
        }
    }

    @ResponseBody
    @RequestMapping("updateProLimitVal.do")
    public ResponseData updateProLimitVal(@RequestParam("orgCd") String orgCd , @RequestParam("value")Double value){
        logger.info("修改包牌比例限制，orgCd:"+orgCd + ",value:" + value);
        ResponseData responseData = new ResponseData(ResponseData.FAIL_CODE,"修改包牌比例限制失败") ;
        SysOrgBpCfgCondition  limitCon = new SysOrgBpCfgCondition();
        limitCon.setOrgTyp(2);
        limitCon.setOrgCd(orgCd);
        limitCon.setLimitTyp(1); //  限制比例
        SysOrgBpCfgVO orgLimit = prjOrgBpLimitService.getBpOrgLimit(limitCon);
        logger.info("查询包牌比例限制" + JSON.toJSONString(orgLimit));
        // 更新包牌比例限制
        SysOrgBpCfgVO sysOrgBpCfgVO = new SysOrgBpCfgVO() ;
        sysOrgBpCfgVO.setOrgCd(orgCd);
        sysOrgBpCfgVO.setOrgTyp(2);
        sysOrgBpCfgVO.setLimitTyp(1);
        sysOrgBpCfgVO.setLimitVal(Double.valueOf(value));
        Integer integer = prjOrgBpLimitService.updateOrgBpLimitCfg(sysOrgBpCfgVO);
        if (integer != null && integer > 0){
            // 插入修改记录
            SysOrgBpCfgEditLogVO vo = new SysOrgBpCfgEditLogVO() ;
            SysUsrDTO sysUsrDTO = sysUsrApiService.selectSysUsrById(CurrentThreadContext.getCurrentUserId(),"11000","0000");
            logger.info("查询用户信息:" + JSON.toJSONString(sysUsrDTO));
            vo.setUserId(CurrentThreadContext.getCurrentUserId());
            vo.setUserName(CurrentThreadContext.getCurrentUserName()); // 工号
            vo.setOrgCd(orgCd);
            vo.setOriginVal(orgLimit.getLimitVal());
            vo.setNewVal(value);
            vo.setUserNo(sysUsrDTO.getUsrNm());
            vo.setCrtTm(new Date());
            vo.setModTm(new Date());
            vo.setIsDel(0);
            vo.setEditTyp(1);
            Integer result = prjOrgBpLimitService.addSysOrgCfgEditLog(vo);
            if (result != null && result > 0){
                responseData.setCode(ResponseData.SUCCESS_CODE);
                responseData.setData(1);
                responseData.setMessage("修改成功");
            }
        }
        return responseData ;
    }

    @ResponseBody
    @RequestMapping("getSubBpCfgList.do")
    public ResponseData getSubBpCfgList(){
        try{
            ResponseData responseData = new ResponseData();

            SysOrgBpCfgCondition condition = new SysOrgBpCfgCondition();
            Date now = new Date() ;
            condition.setStartDt(format.parse(format.format(now)));
            condition.setEndDt(now);
            condition.setUserId(CurrentThreadContext.getCurrentUserId());
            // 获取当前用户权限下的所有分公司
            List<SysUsrDatAuthRDTO> auList = this.priorityApiService.searchSysUsrDatAuthRWithOrgCdList(condition.getUserId(), null, "11000");
            logger.info("用户数据权限关系：" + JSON.toJSONString(auList));
            List subIds = new ArrayList();
            List orgCds = new ArrayList();
            for (SysUsrDatAuthRDTO dto : auList) {
                if(dto.getIsChg() == BaseConstant.IS_YESNO_YES){
                    subIds.add(dto.getOrgId());
                }
                orgCds.add(dto.getOrgCd()) ;
            }
            SysOrgQueryCondition queryCondition = new SysOrgQueryCondition();
            queryCondition.setSysCd(CurrentThreadContext.getCurrentSysCd());
            queryCondition.setOrgCdList(orgCds);
            List<SysOrgDTO> sysOrgDTOS = sysOrgApiService.searchSysOrgList(queryCondition); // 所有用户权限下的组织架构
            logger.info("用户权限下所有组织架构：" + JSON.toJSONString(sysOrgDTOS));
            List<SysOrgDTO> list = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(subIds)){
                list = sysOrgApiService.searchRecuOrgWithchildBy(subIds, "11000"); // 权限下的分公司列表
                logger.info("子架构:" + JSON.toJSONString(list));
            }
            if (CollectionUtils.isNotEmpty(list)){
                sysOrgDTOS.addAll(list) ;
            }
            List<SysOrgBpCfgVO> proOrgList = prjOrgBpLimitService.getBpOrgLimitCfgList(PrjBscInfoConstant.CODE_BU_ORG_CD_ZK);
            logger.info("省公司配置列表:"+JSON.toJSONString(proOrgList));
            Map<String,SysOrgBpCfgVO> proMap = new HashMap<>() ;
            proOrgList.forEach(proOrg->{
                proMap.put(proOrg.getOrgCd(),proOrg) ;
            });
            List<JSONObject> cfgList = new ArrayList();
            // 放到map里，去重
            for (SysOrgDTO sysOrgDTO:sysOrgDTOS) {
                // 如果（架构级别）是分公司，查询它下面的支付表总数和包牌数
                String proNm = null;
                SysOrgBpCfgVO subBpCfg = null ;
                if (sysOrgDTO.getOrgLvl() == 4L && !sysOrgDTO.getOrgCd().substring(0, 12).equals("000000010025")) {
                    logger.info("分公司包牌比例配置信息：orgCd:{}", sysOrgDTO.getOrgCd());
                    // 查询分公司支付表总数和包牌业务支付表数量
                    condition.setOrgCd(sysOrgDTO.getOrgCd());
                    subBpCfg = prjOrgBpLimitService.getSubBpCfg(condition);
                    if (sysOrgDTO.getOrgCd().substring(0, 12) == null || proMap.get(sysOrgDTO.getOrgCd().substring(0, 12)) == null) {
                        continue;
                    } else {
                        proNm = proMap.get(sysOrgDTO.getOrgCd().substring(0, 12)).getOrgNm();
                    }
                }else if(sysOrgDTO.getOrgLvl() == 5L && sysOrgDTO.getOrgCd().substring(0, 12).equals("000000010025")){
                    condition.setOrgCd(sysOrgDTO.getOrgCd());
                    proNm = proMap.get(sysOrgDTO.getOrgCd().substring(0, 16)).getOrgNm();
                    subBpCfg = prjOrgBpLimitService.getSubBpCfg(condition);
                }else {
                    continue;
                }
                JSONObject obj = new JSONObject();
                obj.put("proNm", proNm); // 省公司名称
                obj.put("orgCd", sysOrgDTO.getOrgCd()); // 分公司编码
                obj.put("orgNm", sysOrgDTO.getOrgNm()); // 分公司名称
                obj.put("allCount", subBpCfg.getAllCount()); // 总数
                obj.put("bpCount", subBpCfg.getBpCount()); // 包牌数
                cfgList.add(obj);
            }
            JSONObject [] cfgArrList = new JSONObject[cfgList.size()] ;
            for (int i=0;i<cfgArrList.length;i++){
                cfgArrList[i] = cfgList.get(i) ;
            }
            for (int i = 0; i < cfgArrList.length; i++){
                for (int j = 0; j < cfgArrList.length - 1 - i; j++){
                    if (cfgArrList[j].get("proNm") != null && cfgArrList[j+1].get("proNm") != null && cfgArrList[j + 1].get("proNm").toString().compareTo(cfgArrList[j].get("proNm").toString()) < 0) {
                        JSONObject temp = cfgArrList[j + 1];
                        cfgArrList[j + 1] = cfgArrList[j];
                        cfgArrList[j] = temp;
                    }
                }
            }
            JSONArray cfgList1 = new JSONArray() ;
            for (JSONObject object :cfgArrList){
                cfgList1.add(object);
            }
            if (CollectionUtils.isNotEmpty(cfgList1)){
                responseData.setData(cfgList1);
                responseData.setCode(ResponseData.SUCCESS_CODE);
                responseData.setSuccess(true);
            }
            return responseData ;
        }catch (Exception e){
            logger.error("获取分公司包牌配置信息列表失败{}",e);
            throw new BaseException("查询分公司包牌比例配置列表失败");
        }
    }
}
